﻿using System;
using System.Collections.ObjectModel;
using System.Xml.Linq;
using OAuth.Providers.ETrade.Model;
using ReactiveOAuth;

#if WINDOWS_PHONE
using Microsoft.Phone.Reactive;
#else
using System.Reactive.Linq;
#endif

namespace OAuth.Providers.ETrade
{

    public class Accounts
    {

        public AccessToken AccessToken { private get; set; }

        public Accounts(AccessToken accessToken)
        {
            AccessToken = accessToken;
        }

        public event ObjectEventHandler<ObservableCollection<Account>> GetAccountListCompleted;
        public event ObjectEventHandler<String> GetAccountListError;

        public void GetAccountList()
        {
            var accounts = new ObservableCollection<Account>();

            var client = new OAuthClient(Settings.ConsumerKey, Settings.ConsumerSecret, AccessToken);
            client.Url = Settings.AccountListUrl;
            client.MethodType = MethodType.Get;
            client.GetResponseText()
                .Select(XElement.Parse)
                .SelectMany(x => x.Descendants("Account"))
                .Select(x => new Account
                                 {
                                     Id = x.Element("accountId").Value,
                                     Description = x.Element("accountDesc").Value,
                                     MarginLevel = (MarginLevels)Enum.Parse(typeof(MarginLevels), x.Element("marginLevel").Value, true),
                                     NetAccountValue = double.Parse(x.Element("netAccountValue").Value),
                                     RegistrationType = (RegistrationTypes)Enum.Parse(typeof(RegistrationTypes), x.Element("registrationType").Value, true)
                                 })
                .ObserveOnDispatcher()
                .Subscribe(accounts.Add,
                           ex =>
                           {
                               if (GetAccountListError != null)
                                   GetAccountListError(ex.Message);
                           },
                           () =>
                               {
                                   if (GetAccountListCompleted != null)
                                       GetAccountListCompleted(accounts);
                               });
        }

        public event ObjectEventHandler<ObservableCollection<Alert>> GetAlertsCompleted;
        public event ObjectEventHandler<String> GetAlertsError;

        public void GetAlerts()
        {
            var alerts = new ObservableCollection<Alert>();

            var client = new OAuthClient(Settings.ConsumerKey, Settings.ConsumerSecret, AccessToken);
            client.Url = Settings.AccountAlertsUrl;
            client.MethodType = MethodType.Get;
            client.GetResponseText()
                .Select(XElement.Parse)
                .SelectMany(x => x.Element("Alerts").Descendants("Alert"))
                .Select(x => new Alert
                {
                    Id = x.Element("alertId").Value,
                    DateTime = x.Element("dateTime").Value.ToDateTime(),
                    Subject = x.Element("subject").Value,
                    IsRead = x.Element("readFlag").Value.ToUpper() == "READ",
                    Symbol = x.Element("symbol").Value
                })
                .ObserveOnDispatcher()
                .Subscribe(alerts.Add,
                           ex =>
                           {
                               if (GetAlertsError != null)
                                   GetAlertsError(ex.Message);
                           },
                           () =>
                           {
                               if (GetAlertsCompleted != null)
                                   GetAlertsCompleted(alerts);
                           });
        }

        public event ObjectEventHandler<AlertDetails> GetAlertDetailsCompleted;
        public event ObjectEventHandler<String> GetAlertDetailsError;

        public void GetAlertDetails(string alertId)
        {
            var client = new OAuthClient(Settings.ConsumerKey, Settings.ConsumerSecret, AccessToken);
            client.Url = string.Concat(Settings.AccountAlertsUrl, "/", alertId);
            client.MethodType = MethodType.Get;
            client.GetResponseText()
                .Select(XElement.Parse)
                .Select(x => new AlertDetails
                                 {
                                     Id = x.Element("alertId").Value,
                                     CreateDate = x.Element("dateTime").Value.ToDateTime(),
                                     ReadDate = x.Element("readDate").Value.ToDateTime(),
                                     Subject = x.Element("subject").Value,
                                     Message = x.Element("msgText").Value
                                 })
                .ObserveOnDispatcher()
                .Subscribe(a =>
                               {
                                   if (GetAlertDetailsCompleted != null)
                                       GetAlertDetailsCompleted(a);
                               },
                           ex =>
                               {
                                   if (GetAlertDetailsError != null)
                                       GetAlertDetailsError(ex.Message);
                               });
        }

        public event ObjectEventHandler DeleteAlertDetailsCompleted;
        public event ObjectEventHandler<String> DeleteAlertDetailsError;

        public void DeleteAlert(string alertId)
        {
            var client = new OAuthClient(Settings.ConsumerKey, Settings.ConsumerSecret, AccessToken);
            client.Url = string.Concat(Settings.AccountAlertsUrl, "/", alertId);
            client.MethodType = MethodType.Delete;
            client.GetResponseText()
                .Select(XElement.Parse)
                .Select(x => x.Element("result").Value)
                .ObserveOnDispatcher()
                .Subscribe(a =>
                               {
                                   if (DeleteAlertDetailsCompleted != null)
                                   {
                                       if (a.ToUpper() == "SUCCESS")
                                           DeleteAlertDetailsCompleted();
                                       else if (DeleteAlertDetailsError != null)
                                           DeleteAlertDetailsError(a);
                                   }
                               },
                           ex =>
                               {
                                   if (DeleteAlertDetailsError != null)
                                       DeleteAlertDetailsError(ex.Message);
                               });
        }

    }

}